import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rapid_kit/rapid_kit.dart';
import 'package:timeline_tile/timeline_tile.dart';
import '../../theme.dart';
import '../../utils/snack_tips.dart';
import '../../widgets/global_widgets.dart';
import '../../widgets/lifecycle_aware.dart';
import './live/live_middle.dart';

/// 云录像页面
class CloudReplayPage extends StatefulWidget {
  final String deviceId;
  final String deviceName;

  const CloudReplayPage({super.key, required this.deviceId, required this.deviceName});

  @override
  State<CloudReplayPage> createState() => _CloudReplayPageState();
}

class _CloudReplayPageState extends LifecycleAwareState<CloudReplayPage> with WidgetsBindingObserver {
  static const String _tag = "_CloudReplayPage_";

  late String _deviceId;
  late String _deviceName;
  bool _audioMuted = false;
  bool _eventsLoading = true;

  late CloudReplayStream _stream;
  late Player _player;

  int _currentPartStartTimestampInMs = 0;
  int _currentPartEndTimestampInMs = 0;
  int _currentTimestampInMs = 0;
  bool _recordClicked = false;
  bool _seekDragging = false;
  int _seekPosition = 0;
  bool _rendering = false;
  bool _playCompleted = false;

  CloudRecordIndexPacket? _recordIndexPacket;

  CloudReplaySpeed _speed = CloudReplaySpeed.x1;

  DateTime _selectedDate = DateTime.now();
  final DateTime _todayDate = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("云录像", style: TextStyle(color: SampleThemeConfigure.colorPrimary)),
        backgroundColor: SampleThemeConfigure.colorBackground,
        leading: IconButton(
          icon: const Icon(Icons.arrow_back, color: SampleThemeConfigure.colorPrimary),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
      body: _root(),
    );
  }

  Widget _root() {
    return LayoutBuilder(
      builder: (context, constraints) {
        double width = constraints.maxWidth;
        double height = width * 9 / 16;

        return Column(
          children: <Widget>[
            _top(width, height),
            _seekbarWithTimestamps(),
            _middle(),
            Expanded(
              child: _bottom(),
            ),
          ],
        );
      },
    );
  }

  Widget _seekbarWithTimestamps() {
    if (_currentTimestampInMs == 0) {
      return const SizedBox();
    }

    int current = _currentTimestampInMs - _currentPartStartTimestampInMs;
    int total = _currentPartEndTimestampInMs - _currentPartStartTimestampInMs;

    if (_seekDragging) {
      current = _seekPosition;
    }

    if (current < 0) {
      current = 0;
    }

    if (total < 0) {
      total = 0;
    }

    if (current > total) {
      current = total;
    }

    return StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        return Container(
          height: 50,
          padding: const EdgeInsets.symmetric(horizontal: 10),
          color: SampleThemeConfigure.colorVideoBackground,
          child: Row(
            children: [
              Text(
                _currentTimestampInMs.millisecondToHHmmss(),
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 12,
                ),
              ),
              Expanded(
                child: Slider(
                  value: _seekDragging ? _seekPosition.toDouble() : current.toDouble(),
                  min: 0,
                  max: total.toDouble(),
                  onChangeStart: (value) {
                    _seekDragging = true;
                    _seekPosition = value.toInt();
                  },
                  onChangeEnd: (value) {
                    if (_seekDragging) {
                      _player.stop();
                      _player.start();
                      _stream.seek((_seekPosition / 1000 + _currentPartStartTimestampInMs / 1000).toInt());
                    }
                    _seekDragging = false;
                  },
                  onChanged: (value) {
                    if (_seekDragging) _seekPosition = value.toInt();
                  },
                  activeColor: Colors.white,
                  inactiveColor: Colors.grey,
                ),
              ),
              Text(
                _currentPartEndTimestampInMs.millisecondToHHmmss(),
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 12,
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  String _formatTime(int milliseconds) {
    Duration duration = Duration(milliseconds: milliseconds);
    int hours = duration.inHours;
    int minutes = duration.inMinutes % 60;
    int seconds = duration.inSeconds % 60;

    if (hours > 0) {
      return '$hours:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
    } else {
      return '${minutes.toString()}:${seconds.toString().padLeft(2, '0')}';
    }
  }

  Widget _middle() {
    return Container(
      height: 100,
      width: double.infinity,
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.only(
          bottomLeft: Radius.circular(30),
          bottomRight: Radius.circular(30),
        ),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          _muteControl(),
          _screenshot(),
          _speedControl(),
        ],
      ),
    );
  }

  IconButton _speedControl() {
    return IconButton(
      icon: const Icon(Icons.speed_rounded, size: 25, color: SampleThemeConfigure.colorTextPrimary),
      onPressed: () {
        _speed = _speed == CloudReplaySpeed.x1 ? CloudReplaySpeed.x4 : CloudReplaySpeed.x1;
        _stream.setSpeed(_speed);
        SnackTips.show(context, "速度切换为${_speed.name}");
      },
    );
  }

  IconButton _screenshot() {
    return IconButton(
      icon: const Icon(Icons.camera_alt, size: 25, color: SampleThemeConfigure.colorTextPrimary),
      onPressed: () {},
    );
  }

  IconButton _muteControl() {
    return IconButton(
      icon: Icon(_audioMuted ? Icons.volume_off_rounded : Icons.volume_up_rounded, size: 25, color: SampleThemeConfigure.colorTextPrimary),
      onPressed: () => _onVolumeTap(),
    );
  }

  void _onVolumeTap() {
    if (_player.isMute()) {
      _player.mute(false);
    } else {
      _player.mute(true);
    }

    setState(() {
      _audioMuted = _player.isMute();
    });
  }

  Widget _top(double width, double height) {
    return Container(
      width: width,
      height: height,
      color: SampleThemeConfigure.colorVideoBackground,
      child: Stack(
        alignment: Alignment.center,
        children: [
          _buildVideoPlayerBody(),
          if (!_recordClicked)
            Text(
              "点击下方列表选择录像片段",
              style: const TextStyle(
                color: Colors.white,
                fontSize: 16, // 可根据需要调整字体大小
              ),
            ),
          if (_playCompleted)
            Text(
              "这段录像播完了",
              style: const TextStyle(
                color: Colors.white,
                fontSize: 16, // 可根据需要调整字体大小
              ),
            ),
          if (_seekDragging) //
            Text(
              "松手以播放 ${(_seekPosition / 1000 + _currentPartStartTimestampInMs / 1000).toInt().toHHmmss()}",
              style: const TextStyle(
                color: Colors.white,
                fontSize: 16, // 可根据需要调整字体大小
              ),
            ),
        ],
      ),
    );
  }

  Widget _bottom() {
    return Column(
      children: <Widget>[
        _categoriesBar(),
        _listContainer(),
      ],
    );
  }

  Container _categoriesBar() {
    return Container(
      height: 60.0,
      padding: const EdgeInsets.symmetric(horizontal: 16.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          _datePicker(),
        ],
      ),
    );
  }

  GestureDetector _datePicker() {
    return GestureDetector(
      onTap: () async => _onPickDate(),
      child: Row(
        children: <Widget>[
          Text(
            _formattedDateString(),
            style: const TextStyle(fontSize: 16.0, color: SampleThemeConfigure.colorTextPrimary),
          ),
          const Padding(
            padding: EdgeInsets.only(left: 0),
            child: Icon(
              Icons.arrow_drop_down_rounded,
              size: 30,
              color: SampleThemeConfigure.colorTextPrimary,
            ),
          )
        ],
      ),
    );
  }

  String _formattedDateString() {
    String formattedDate = _selectedDate.toChineseDate();

    if (_todayDate.day == _selectedDate.day) {
      formattedDate = "$formattedDate | 今天";
    }
    return formattedDate;
  }

  void _onPickDate() async {
    DateTime? pickedDate = await showDatePicker(
      context: context,
      initialDate: _selectedDate,
      firstDate: DateTime(2000),
      lastDate: DateTime(2101),
    );

    if (pickedDate != null && pickedDate != _selectedDate) {
      setState(() {
        _selectedDate = pickedDate;
        _eventsLoading = true;
      });
    }

    _loadRecordIndex();
  }

  Widget _listContainer() {
    if (_eventsLoading) {
      return Expanded(
        child: createCenterLoading(size: 20.0),
      );
    }

    if (_recordIndexPacket?.list.isEmpty ?? true) return _emptyTips();

    return Expanded(
      child: Padding(padding: const EdgeInsets.only(left: 16.0, right: 16.0), child: _eventList()),
    );
  }

  ListView _eventList() {
    return ListView.builder(
        itemCount: _recordIndexPacket?.list.length ?? 0,
        itemBuilder: (context, index) {
          return _buildTapItem(
            _recordIndexPacket!.list[index],
            isFirst: index == 0,
            isLast: index == _recordIndexPacket!.list.length - 1,
          );
        });
  }

  Widget _buildTapItem(CloudRecordIndex record, {bool isFirst = false, bool isLast = false}) {
    return GestureDetector(
      onTap: () async {
        _stream.stop();
        _stream.prepare(record.startTimestampSecond, record.endTimestampSecond, record.storageId);
        _stream.start();

        _player.stop();
        _player.start();

        setState(() {
          _recordClicked = true;
          _playCompleted = false;
          _seekDragging = false;
          _currentTimestampInMs = 0;
          _currentPartStartTimestampInMs = record.startTimestampSecond * 1000;
          _currentPartEndTimestampInMs = record.endTimestampSecond * 1000;
        });
      },
      child: _buildItem(record, isFirst: isFirst, isLast: isLast),
    );
  }

  Widget _buildItem(CloudRecordIndex record, {bool isFirst = false, bool isLast = false}) {
    return TimelineTile(
        alignment: TimelineAlign.manual,
        lineXY: 0.3,
        isFirst: isFirst,
        isLast: isLast,
        indicatorStyle: IndicatorStyle(
          width: 40,
          iconStyle: IconStyle(
            color: Colors.white,
            fontSize: 14,
            iconData: Icons.emergency_recording_rounded,
          ),
          color: SampleThemeConfigure.colorPrimary,
          padding: const EdgeInsets.all(6),
        ),
        beforeLineStyle: const LineStyle(
          color: SampleThemeConfigure.colorTextHint,
          thickness: 2,
        ),
        afterLineStyle: isLast
            ? null
            : const LineStyle(
                color: SampleThemeConfigure.colorTextHint,
                thickness: 2,
              ),
        startChild: Container(
          padding: const EdgeInsets.all(5),
          alignment: Alignment.centerRight,
          child: Text("${record.startTimestampSecond.toHHmmss()} 至 ${record.endTimestampSecond.toHHmmss()}",
              style: const TextStyle(color: SampleThemeConfigure.colorTextHint, fontSize: 12)),
        ),
        endChild: Container(
          padding: const EdgeInsets.all(16.0),
          alignment: Alignment.centerLeft,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(height: 20),
              Text(
                _formatDuration(record.durationSecond),
                style: const TextStyle(color: SampleThemeConfigure.colorTextPrimary, fontSize: 12),
              ),
              const SizedBox(height: 20),
            ],
          ),
        ));
  }

  String _formatDuration(int seconds) {
    if (seconds < 0) {
      return "";
    }

    final int hours = seconds ~/ 3600;
    final int minutes = (seconds % 3600) ~/ 60;
    final int remainingSeconds = seconds % 60;

    final List<String> parts = [];

    if (hours > 0) {
      parts.add('$hours小时');
    }
    if (minutes > 0 || hours > 0) {
      parts.add('$minutes分钟');
    }
    parts.add('$remainingSeconds秒');

    return parts.join('');
  }

  Expanded _emptyTips() {
    return Expanded(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            Icon(Icons.event_note, size: 50, color: SampleThemeConfigure.colorPrimary),
            SizedBox(height: 10),
            Text(
              '没有录像',
              style: TextStyle(
                fontSize: 14,
                color: SampleThemeConfigure.colorPrimary,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildVideoPlayerBody() {
    return Stack(
      children: [
        Positioned.fill(
          child: Container(color: SampleThemeConfigure.colorVideoBackground),
        ),
        _player.texture(),
        if (!_rendering && _recordClicked && !_playCompleted) bufferingWidget()
      ],
    );
  }

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addObserver(this);

    _deviceId = widget.deviceId;
    _deviceName = widget.deviceName;
    _preparePlayer();

    _loadRecordIndex();
  }

  @override
  void dispose() {
    super.dispose();

    Logging.i(_tag, "dispose ...");

    _player.mute(true);

    _stream.stop();
    _player.stop();

    _player.destroy();
    _stream.destroy();

    WidgetsBinding.instance.removeObserver(this);

    Logging.i(_tag, "dispose done");
  }

  void _preparePlayer() {
    _stream = CloudReplayStream.create(_deviceId);
    _stream.onChunkNotFound = (timestampS) {
      // handle chunk not found
    };

    _stream.onComplete = () {
      // handle stream complete
    };

    final providerPtr = _stream.provider(cameraIndex: 0)!;

    _player = Player.create();
    _player.prepare(providerPtr);
    _player.onUniversalTimestamp = (timestamp) {
      // use timestamp to sync your ui, e.g. seek bar / timeline
      setState(() {
        _currentTimestampInMs = timestamp;
      });
    };
    _player.onRenderState = (state) {
      setState(() {
        _rendering = state != RenderState.buffering && state != RenderState.completed;
      });

      _playCompleted = state == RenderState.completed;
    };
  }

  void _loadRecordIndex() async {
    final date = _selectedDate.toStandardDate();
    final response = await StorageService.listRecords(_deviceId, date);
    if (response.success) {
      _recordIndexPacket = response.data;
    }

    setState(() {
      _eventsLoading = false;
    });
  }
}
